using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Tilemaps;
using System;

// 施工类
public class ConstructionLayer : TilemapLayer
{

    // 存储已建造的建筑物的字典
    private Dictionary<Vector3Int, Buildable> _buildables = new Dictionary<Vector3Int, Buildable>();

    [SerializeField]
    private CollisionLayer _collisionLayer;

    // 定义私有成员变量 _collisionTileBase，用于存储碰撞 Tilemap 中的 TileBase
    // [SerializeField]
    // private TileBase _collisionTileBase;

    // 在指定坐标上建造一个可建造物品
    public void Build(Vector3Int coords, BuildableItem item)
    {

        GameObject itemObject = null;

        // 如果可建造物品有瓦片，则将其设置到对应坐标上
        if (item.Tile != null)
        {
            _tilemap.SetTile(coords, item.Tile);
            //建造偏移
            var tileChangeData = new TileChangeData(
                coords,
                item.Tile,
                Color.white,
                Matrix4x4.Translate(item.TileOffset)
            );
            _tilemap.SetTile(tileChangeData, false);
        }

        if (item.gameObject != null)
        {
            //_tilemap.cellSize 是获取 Tilemap 的单个瓦片的大小。它返回的是一个 Vector3 类型的值，表示瓦片在三维空间中的尺寸
            //itemObject = Instantiate(item.gameObject, coords + _tilemap.cellSize / 2, Quaternion.identity);
            //_tilemap.GetCellCenterWorld(coords) 来获取瓦片中心在世界坐标中的位置。
            itemObject = Instantiate(item.gameObject, _tilemap.GetCellCenterWorld(coords), Quaternion.identity);
        }

        // 创建建筑物对象
        var buildable = new Buildable(item, coords, _tilemap, itemObject);

        if (item.UseCustomCollisionSpace)
        {
            // 如果使用自定义碰撞区域，将碰撞区域设置为有碰撞的状态
            _collisionLayer.SetCollisions(buildable, true);
            // 注册建筑物的碰撞区域到已建造的建筑物字典中
            RegisterBuildableCollisionSpace(buildable);
        }
        else
        {
            // 将建筑物添加到已建造的建筑物字典中
            _buildables.Add(coords, buildable);
        }


    }

    // 检查在指定位置是否为空（是否已有建筑物）
    // public bool IsEmpty(Vector3Int coords)
    // {
    //     // 判断指定位置是否已有建筑物
    //     return !_buildables.ContainsKey(coords);
    // }

    //删除建筑
    public void Destroy(Vector3Int coords)
    {
        if (!_buildables.ContainsKey(coords)) return;

        var buildable = _buildables[coords];
        if (buildable.BuildableType.UseCustomCollisionSpace)
        {
            _collisionLayer.SetCollisions(buildable, false);
            UnregisterBuildableCollisionSpace(buildable);
        }
        _buildables.Remove(coords);
        buildable.Destroy();
    }

    // 从已建造的建筑物字典中注销建筑物的碰撞区域
    private void RegisterBuildableCollisionSpace(Buildable buildable)
    {
        // 迭代遍历建筑物的碰撞区域，并将碰撞区域与建筑物关联并添加到已建造的建筑物字典中
        buildable.IterateCollisionSpace(tileCoords => _buildables.Add(tileCoords, buildable));
    }

    // 从已建造的建筑物字典中注销建筑物的碰撞区域
    private void UnregisterBuildableCollisionSpace(Buildable buildable)
    {
        buildable.IterateCollisionSpace(tileCoords => { _buildables.Remove(tileCoords); });
    }

    // 检查指定矩形区域是否有建筑物占据
    private bool IsRectOccupied(Vector3Int coords, RectInt rect)
    {
        return rect.Iterate(coords, tileCoords => _buildables.ContainsKey(tileCoords));
    }

    // 检查指定位置及其周围矩形区域是否为空
    public bool IsEmpty(Vector3Int coords, RectInt collisionSpace = default)
    {
        if (!collisionSpace.Equals(default)) return !IsRectOccupied(coords, collisionSpace);
        return !_buildables.ContainsKey(coords) && _tilemap.GetTile(coords) == null;
    }

}